001    /* $RCSfile: JHBCI.java,v $
002     * $Revision: 1.14 $
003     * $Date: 2003/10/04 19:18:38 $
004     * $Author: uwe_guenther $
005     * $State: Exp $
006     *
007     * Created on July 15, 2001, 1:20 PM
008     *
009     * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider;
033    
034    import java.io.ByteArrayInputStream;
035    import java.io.IOException;
036    import java.io.InputStream;
037    import java.net.JarURLConnection;
038    import java.net.MalformedURLException;
039    import java.net.URL;
040    import java.security.AccessController;
041    import java.security.CodeSource;
042    import java.security.PrivilegedAction;
043    import java.security.PrivilegedActionException;
044    import java.security.PrivilegedExceptionAction;
045    import java.security.Provider;
046    import java.security.cert.Certificate;
047    import java.security.cert.CertificateException;
048    import java.security.cert.CertificateFactory;
049    import java.security.cert.X509Certificate;
050    import java.util.Enumeration;
051    import java.util.Vector;
052    import java.util.jar.JarEntry;
053    import java.util.jar.JarFile;
054    import java.util.jar.Manifest;
055    
056    
057    /**
058     * JHBCI - the Provider Class.
059     *
060     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
061     * @version $Revision: 1.14 $
062     */
063    public final class JHBCI extends Provider {
064        
065        /** Info of JHBCI Provider. */
066        private static final String INFO =
067        "JHBCI Provider, by Uwe Guenther <uwe@cscc.de>";
068        
069        /** Provider version. */
070        private static double VERSION;
071        
072        /** Provider name. */
073        private static final String NAME = "JHBCI";
074        
075        /** Initialize the double Version variable with Ant version TAGS. */
076        {
077            try {
078                JHBCI.VERSION = Double.parseDouble("0.06");
079            } catch (NumberFormatException e) {
080                JHBCI.VERSION = 0.0;
081            }
082        }
083        
084        /** Creates new JHBCI provider class. */
085        public JHBCI() {
086            
087            //name, version, info about the provider
088            super(JHBCI.NAME, JHBCI.VERSION, JHBCI.INFO);
089            
090            AccessController.doPrivileged(new PrivilegedAction() {
091                public Object run() {
092                    
093                    //////
094                    //
095                    // DES1Key, DESede2Key, DESede3Key
096                    //
097                    // Cipher, SecretKeyFactory, KeyGenerator
098                    //
099                    //////
100                    
101                    //Cipher DES1Key
102                    put("Cipher.DES1Key",
103                    "de.cscc.crypto.provider.DES1KeyCipherEngine");
104                    //put("Alg.Alias.Cipher.DES", "DES1Key");
105                    
106                    //Cipher DESede2Key
107                    put("Cipher.DESede2Key",
108                    "de.cscc.crypto.provider.DESede2KeyCipherEngine");
109                    
110                    //Cipher DESede3Key
111                    put("Cipher.DESede3Key",
112                    "de.cscc.crypto.provider.DESede3KeyCipherEngine");
113                    
114                    //SecretKeyFactory DES1Key
115                    put("SecretKeyFactory.DES1Key",
116                    "de.cscc.crypto.provider.DES1KeySecretKeyFactoryEngine");
117                    
118                    //SecretKeyFactory DESede2Key
119                    put("SecretKeyFactory.DESede2Key",
120                    "de.cscc.crypto.provider.DESede2KeySecretKeyFactoryEngine");
121                    
122                    //SecretKeyFactory DESede3Key
123                    put("SecretKeyFactory.DESede3Key",
124                    "de.cscc.crypto.provider.DESede3KeySecretKeyFactoryEngine");
125                    
126                    //KeyGenerator DES1Key
127                    put("KeyGenerator.DES1Key", 
128                    "de.cscc.crypto.provider.DES1KeySecretKeyGeneratorEngine");
129                    
130                    //KeyGenerator DESede2Key
131                    put("KeyGenerator.DESede2Key",
132                    "de.cscc.crypto.provider.DESede2KeySecretKeyGeneratorEngine");
133                    
134                    //KeyGenerator DESede3Key
135                    put("KeyGenerator.DESede3Key",
136                    "de.cscc.crypto.provider.DESede3KeySecretKeyGeneratorEngine");
137          
138                    
139                    //////
140                    //
141                    // RSA
142                    //
143                    // Cipher, Signature, KeyFactory, KeyPairGenerator
144                    //
145                    //////                
146                    
147                    //Cipher RSA
148                    put("Cipher.RSA",
149                    "de.cscc.crypto.provider.RSACipherEngine");
150    
151                    //Signature ISO9796-1WithRSA
152                    put("Signature.ISO9796-1WithRSA",
153                    "de.cscc.crypto.provider.ISO9796Part1WithRSASignatureEngine"); 
154    
155                    //Signature RIPEMD160WithISO9796-1AndRSA
156                    put("Signature.RIPEMD160WithISO9796-1AndRSA",
157                    "de.cscc.crypto.provider.RIPEMD160WithISO9796Part1AndRSASignatureEngine");                
158                    
159                    //KeyFactory RSA
160                    put("KeyFactory.RSA",
161                    "de.cscc.crypto.provider.RSAKeyFactoryEngine");                
162                    
163                    //KeyPairGenerator RSA
164                    put("KeyPairGenerator.RSA",
165                    "de.cscc.crypto.provider.RSAKeyPairGeneratorEngine");
166                    
167          
168                    //////
169                    //
170                    // RIPEMD160
171                    //
172                    // MessageDigest
173                    //
174                    //////                
175                                   
176                    //MessageDigest RIPEMD160
177                    put("MessageDigest.RIPEMD160",
178                    "de.cscc.crypto.provider.RIPEMD160MessageDigestEngine");
179    
180                    return null;
181                }
182            });
183        }
184    
185    
186        
187        /*
188         * At these point follows only static Self Integrity Checking Stuff.
189         * You have to put the following code in any JCE SPI-Class in this
190         * Provider: 
191         *
192         * <pre>
193         * if (JHBCI.selfIntegrityChecking() == false) {
194         *     throw new SecurityException("JHBCI-Provider is tampered.");
195         * }
196         * </pre>
197         *
198         * Note: That is only necessary for JCE SPI-Classes not for JCA SPI-Classes.
199         */
200        
201        /**
202         * For efficiency, keep track of whether or not the provider
203         * has already been verified to avoid doing it multiple times
204         * unnecessarily.
205         */
206        private static boolean verifiedSelfIntegrity = false;
207    
208        /** 
209         * Provider's signing cert which is used to sign the jar. 
210         */
211        private static X509Certificate providerCert = null;
212    
213        /** Raw bytes of provider's own code signing cert.
214         *  This is the Guenther-Elektronik JCE cert. 
215         */
216        private static final byte[] bytesOfProviderCert = {
217            (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0xa1,
218            (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0x5f,
219            (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
220            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x17,
221            (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x07,
222            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce,
223            (byte) 0x38, (byte) 0x04, (byte) 0x03, (byte) 0x05,
224            (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x90,
225            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
226            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
227            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55,
228            (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
229            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
230            (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02,
231            (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x12,
232            (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03,
233            (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13,
234            (byte) 0x09, (byte) 0x50, (byte) 0x61, (byte) 0x6c,
235            (byte) 0x6f, (byte) 0x20, (byte) 0x41, (byte) 0x6c,
236            (byte) 0x74, (byte) 0x6f, (byte) 0x31, (byte) 0x1d,
237            (byte) 0x30, (byte) 0x1b, (byte) 0x06, (byte) 0x03,
238            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13,
239            (byte) 0x14, (byte) 0x53, (byte) 0x75, (byte) 0x6e,
240            (byte) 0x20, (byte) 0x4d, (byte) 0x69, (byte) 0x63,
241            (byte) 0x72, (byte) 0x6f, (byte) 0x73, (byte) 0x79,
242            (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x6d,
243            (byte) 0x73, (byte) 0x20, (byte) 0x49, (byte) 0x6e,
244            (byte) 0x63, (byte) 0x31, (byte) 0x23, (byte) 0x30,
245            (byte) 0x21, (byte) 0x06, (byte) 0x03, (byte) 0x55,
246            (byte) 0x04, (byte) 0x0b, (byte) 0x13, (byte) 0x1a,
247            (byte) 0x4a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
248            (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66,
249            (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72,
250            (byte) 0x65, (byte) 0x20, (byte) 0x43, (byte) 0x6f,
251            (byte) 0x64, (byte) 0x65, (byte) 0x20, (byte) 0x53,
252            (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x69,
253            (byte) 0x6e, (byte) 0x67, (byte) 0x31, (byte) 0x1c,
254            (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03,
255            (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13,
256            (byte) 0x13, (byte) 0x4a, (byte) 0x43, (byte) 0x45,
257            (byte) 0x20, (byte) 0x43, (byte) 0x6f, (byte) 0x64,
258            (byte) 0x65, (byte) 0x20, (byte) 0x53, (byte) 0x69,
259            (byte) 0x67, (byte) 0x6e, (byte) 0x69, (byte) 0x6e,
260            (byte) 0x67, (byte) 0x20, (byte) 0x43, (byte) 0x41,
261            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d,
262            (byte) 0x30, (byte) 0x31, (byte) 0x30, (byte) 0x36,
263            (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x35,
264            (byte) 0x34, (byte) 0x30, (byte) 0x34, (byte) 0x39,
265            (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x30,
266            (byte) 0x36, (byte) 0x30, (byte) 0x36, (byte) 0x31,
267            (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x34,
268            (byte) 0x30, (byte) 0x34, (byte) 0x39, (byte) 0x5a,
269            (byte) 0x30, (byte) 0x62, (byte) 0x31, (byte) 0x1d,
270            (byte) 0x30, (byte) 0x1b, (byte) 0x06, (byte) 0x03,
271            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13,
272            (byte) 0x14, (byte) 0x53, (byte) 0x75, (byte) 0x6e,
273            (byte) 0x20, (byte) 0x4d, (byte) 0x69, (byte) 0x63,
274            (byte) 0x72, (byte) 0x6f, (byte) 0x73, (byte) 0x79,
275            (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x6d,
276            (byte) 0x73, (byte) 0x20, (byte) 0x49, (byte) 0x6e,
277            (byte) 0x63, (byte) 0x31, (byte) 0x23, (byte) 0x30,
278            (byte) 0x21, (byte) 0x06, (byte) 0x03, (byte) 0x55,
279            (byte) 0x04, (byte) 0x0b, (byte) 0x13, (byte) 0x1a,
280            (byte) 0x4a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
281            (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66,
282            (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72,
283            (byte) 0x65, (byte) 0x20, (byte) 0x43, (byte) 0x6f,
284            (byte) 0x64, (byte) 0x65, (byte) 0x20, (byte) 0x53,
285            (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x69,
286            (byte) 0x6e, (byte) 0x67, (byte) 0x31, (byte) 0x1c,
287            (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03,
288            (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13,
289            (byte) 0x13, (byte) 0x47, (byte) 0x75, (byte) 0x65,
290            (byte) 0x6e, (byte) 0x74, (byte) 0x68, (byte) 0x65,
291            (byte) 0x72, (byte) 0x2d, (byte) 0x45, (byte) 0x6c,
292            (byte) 0x65, (byte) 0x6b, (byte) 0x74, (byte) 0x72,
293            (byte) 0x6f, (byte) 0x6e, (byte) 0x69, (byte) 0x6b,
294            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xb7,
295            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c,
296            (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
297            (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04,
298            (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01,
299            (byte) 0x1f, (byte) 0x02, (byte) 0x81, (byte) 0x81,
300            (byte) 0x00, (byte) 0xfd, (byte) 0x7f, (byte) 0x53,
301            (byte) 0x81, (byte) 0x1d, (byte) 0x75, (byte) 0x12,
302            (byte) 0x29, (byte) 0x52, (byte) 0xdf, (byte) 0x4a,
303            (byte) 0x9c, (byte) 0x2e, (byte) 0xec, (byte) 0xe4,
304            (byte) 0xe7, (byte) 0xf6, (byte) 0x11, (byte) 0xb7,
305            (byte) 0x52, (byte) 0x3c, (byte) 0xef, (byte) 0x44,
306            (byte) 0x00, (byte) 0xc3, (byte) 0x1e, (byte) 0x3f,
307            (byte) 0x80, (byte) 0xb6, (byte) 0x51, (byte) 0x26,
308            (byte) 0x69, (byte) 0x45, (byte) 0x5d, (byte) 0x40,
309            (byte) 0x22, (byte) 0x51, (byte) 0xfb, (byte) 0x59,
310            (byte) 0x3d, (byte) 0x8d, (byte) 0x58, (byte) 0xfa,
311            (byte) 0xbf, (byte) 0xc5, (byte) 0xf5, (byte) 0xba,
312            (byte) 0x30, (byte) 0xf6, (byte) 0xcb, (byte) 0x9b,
313            (byte) 0x55, (byte) 0x6c, (byte) 0xd7, (byte) 0x81,
314            (byte) 0x3b, (byte) 0x80, (byte) 0x1d, (byte) 0x34,
315            (byte) 0x6f, (byte) 0xf2, (byte) 0x66, (byte) 0x60,
316            (byte) 0xb7, (byte) 0x6b, (byte) 0x99, (byte) 0x50,
317            (byte) 0xa5, (byte) 0xa4, (byte) 0x9f, (byte) 0x9f,
318            (byte) 0xe8, (byte) 0x04, (byte) 0x7b, (byte) 0x10,
319            (byte) 0x22, (byte) 0xc2, (byte) 0x4f, (byte) 0xbb,
320            (byte) 0xa9, (byte) 0xd7, (byte) 0xfe, (byte) 0xb7,
321            (byte) 0xc6, (byte) 0x1b, (byte) 0xf8, (byte) 0x3b,
322            (byte) 0x57, (byte) 0xe7, (byte) 0xc6, (byte) 0xa8,
323            (byte) 0xa6, (byte) 0x15, (byte) 0x0f, (byte) 0x04,
324            (byte) 0xfb, (byte) 0x83, (byte) 0xf6, (byte) 0xd3,
325            (byte) 0xc5, (byte) 0x1e, (byte) 0xc3, (byte) 0x02,
326            (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5a,
327            (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xf6,
328            (byte) 0x75, (byte) 0xf3, (byte) 0xae, (byte) 0x2b,
329            (byte) 0x61, (byte) 0xd7, (byte) 0x2a, (byte) 0xef,
330            (byte) 0xf2, (byte) 0x22, (byte) 0x03, (byte) 0x19,
331            (byte) 0x9d, (byte) 0xd1, (byte) 0x48, (byte) 0x01,
332            (byte) 0xc7, (byte) 0x02, (byte) 0x15, (byte) 0x00,
333            (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8f,
334            (byte) 0x15, (byte) 0x23, (byte) 0x0b, (byte) 0xcc,
335            (byte) 0xb2, (byte) 0x92, (byte) 0xb9, (byte) 0x82,
336            (byte) 0xa2, (byte) 0xeb, (byte) 0x84, (byte) 0x0b,
337            (byte) 0xf0, (byte) 0x58, (byte) 0x1c, (byte) 0xf5,
338            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00,
339            (byte) 0xf7, (byte) 0xe1, (byte) 0xa0, (byte) 0x85,
340            (byte) 0xd6, (byte) 0x9b, (byte) 0x3d, (byte) 0xde,
341            (byte) 0xcb, (byte) 0xbc, (byte) 0xab, (byte) 0x5c,
342            (byte) 0x36, (byte) 0xb8, (byte) 0x57, (byte) 0xb9,
343            (byte) 0x79, (byte) 0x94, (byte) 0xaf, (byte) 0xbb,
344            (byte) 0xfa, (byte) 0x3a, (byte) 0xea, (byte) 0x82,
345            (byte) 0xf9, (byte) 0x57, (byte) 0x4c, (byte) 0x0b,
346            (byte) 0x3d, (byte) 0x07, (byte) 0x82, (byte) 0x67,
347            (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8e,
348            (byte) 0xba, (byte) 0xd4, (byte) 0x59, (byte) 0x4f,
349            (byte) 0xe6, (byte) 0x71, (byte) 0x07, (byte) 0x10,
350            (byte) 0x81, (byte) 0x80, (byte) 0xb4, (byte) 0x49,
351            (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xe8,
352            (byte) 0x4c, (byte) 0x28, (byte) 0x16, (byte) 0x13,
353            (byte) 0xb7, (byte) 0xcf, (byte) 0x09, (byte) 0x32,
354            (byte) 0x8c, (byte) 0xc8, (byte) 0xa6, (byte) 0xe1,
355            (byte) 0x3c, (byte) 0x16, (byte) 0x7a, (byte) 0x8b,
356            (byte) 0x54, (byte) 0x7c, (byte) 0x8d, (byte) 0x28,
357            (byte) 0xe0, (byte) 0xa3, (byte) 0xae, (byte) 0x1e,
358            (byte) 0x2b, (byte) 0xb3, (byte) 0xa6, (byte) 0x75,
359            (byte) 0x91, (byte) 0x6e, (byte) 0xa3, (byte) 0x7f,
360            (byte) 0x0b, (byte) 0xfa, (byte) 0x21, (byte) 0x35,
361            (byte) 0x62, (byte) 0xf1, (byte) 0xfb, (byte) 0x62,
362            (byte) 0x7a, (byte) 0x01, (byte) 0x24, (byte) 0x3b,
363            (byte) 0xcc, (byte) 0xa4, (byte) 0xf1, (byte) 0xbe,
364            (byte) 0xa8, (byte) 0x51, (byte) 0x90, (byte) 0x89,
365            (byte) 0xa8, (byte) 0x83, (byte) 0xdf, (byte) 0xe1,
366            (byte) 0x5a, (byte) 0xe5, (byte) 0x9f, (byte) 0x06,
367            (byte) 0x92, (byte) 0x8b, (byte) 0x66, (byte) 0x5e,
368            (byte) 0x80, (byte) 0x7b, (byte) 0x55, (byte) 0x25,
369            (byte) 0x64, (byte) 0x01, (byte) 0x4c, (byte) 0x3b,
370            (byte) 0xfe, (byte) 0xcf, (byte) 0x49, (byte) 0x2a,
371            (byte) 0x03, (byte) 0x81, (byte) 0x84, (byte) 0x00,
372            (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x75,
373            (byte) 0xc5, (byte) 0xc4, (byte) 0xdf, (byte) 0xc7,
374            (byte) 0x0f, (byte) 0x37, (byte) 0xb9, (byte) 0x43,
375            (byte) 0x87, (byte) 0xec, (byte) 0x7a, (byte) 0xe0,
376            (byte) 0x5e, (byte) 0x91, (byte) 0xc2, (byte) 0x39,
377            (byte) 0x7a, (byte) 0xf1, (byte) 0xc8, (byte) 0x22,
378            (byte) 0x11, (byte) 0x74, (byte) 0x91, (byte) 0x9c,
379            (byte) 0x8a, (byte) 0xd6, (byte) 0xcb, (byte) 0x93,
380            (byte) 0xc0, (byte) 0x82, (byte) 0xe6, (byte) 0xcb,
381            (byte) 0x3d, (byte) 0x1c, (byte) 0xf9, (byte) 0x76,
382            (byte) 0xe1, (byte) 0xfb, (byte) 0xb2, (byte) 0x03,
383            (byte) 0xc8, (byte) 0xba, (byte) 0x53, (byte) 0x8f,
384            (byte) 0xe3, (byte) 0xba, (byte) 0xfa, (byte) 0xa1,
385            (byte) 0x05, (byte) 0x49, (byte) 0x8f, (byte) 0xcc,
386            (byte) 0x4d, (byte) 0x01, (byte) 0x2c, (byte) 0x95,
387            (byte) 0xa9, (byte) 0x78, (byte) 0xda, (byte) 0x06,
388            (byte) 0xb9, (byte) 0x51, (byte) 0x82, (byte) 0x58,
389            (byte) 0x42, (byte) 0x40, (byte) 0x6c, (byte) 0xf4,
390            (byte) 0x8f, (byte) 0xd6, (byte) 0xe9, (byte) 0x14,
391            (byte) 0x7f, (byte) 0x14, (byte) 0x41, (byte) 0x6d,
392            (byte) 0x02, (byte) 0x83, (byte) 0x19, (byte) 0xa6,
393            (byte) 0x7e, (byte) 0x6e, (byte) 0x71, (byte) 0xeb,
394            (byte) 0xd6, (byte) 0x08, (byte) 0x0a, (byte) 0x70,
395            (byte) 0x3b, (byte) 0x32, (byte) 0x65, (byte) 0x7b,
396            (byte) 0xf3, (byte) 0x6a, (byte) 0x31, (byte) 0x07,
397            (byte) 0x41, (byte) 0xbb, (byte) 0xc8, (byte) 0xd6,
398            (byte) 0x96, (byte) 0x26, (byte) 0x28, (byte) 0xd9,
399            (byte) 0xc2, (byte) 0x84, (byte) 0x58, (byte) 0x82,
400            (byte) 0x72, (byte) 0xa0, (byte) 0x2c, (byte) 0x8a,
401            (byte) 0x33, (byte) 0xd9, (byte) 0x0b, (byte) 0xa9,
402            (byte) 0x79, (byte) 0xfe, (byte) 0x77, (byte) 0x57,
403            (byte) 0xf4, (byte) 0xd2, (byte) 0xc8, (byte) 0x6a,
404            (byte) 0x99, (byte) 0x36, (byte) 0x36, (byte) 0xa3,
405            (byte) 0x76, (byte) 0x30, (byte) 0x74, (byte) 0x30,
406            (byte) 0x11, (byte) 0x06, (byte) 0x09, (byte) 0x60,
407            (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x86,
408            (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x01,
409            (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x02,
410            (byte) 0x00, (byte) 0x87, (byte) 0x30, (byte) 0x0e,
411            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
412            (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff,
413            (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x02,
414            (byte) 0x01, (byte) 0xc6, (byte) 0x30, (byte) 0x1d,
415            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
416            (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04,
417            (byte) 0x14, (byte) 0xbe, (byte) 0xbe, (byte) 0xc6,
418            (byte) 0x10, (byte) 0xba, (byte) 0xd5, (byte) 0x7f,
419            (byte) 0x04, (byte) 0x81, (byte) 0x1a, (byte) 0x69,
420            (byte) 0x35, (byte) 0x34, (byte) 0xe7, (byte) 0x61,
421            (byte) 0x53, (byte) 0xea, (byte) 0x93, (byte) 0xc9,
422            (byte) 0x7b, (byte) 0x30, (byte) 0x0f, (byte) 0x06,
423            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
424            (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04,
425            (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01,
426            (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x1f,
427            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
428            (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
429            (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x65,
430            (byte) 0xe2, (byte) 0xf4, (byte) 0x86, (byte) 0xc9,
431            (byte) 0xd3, (byte) 0x4e, (byte) 0xf0, (byte) 0x91,
432            (byte) 0x4e, (byte) 0x58, (byte) 0xa2, (byte) 0x6a,
433            (byte) 0xf5, (byte) 0xd8, (byte) 0x78, (byte) 0x5a,
434            (byte) 0x9a, (byte) 0xc1, (byte) 0xa6, (byte) 0x30,
435            (byte) 0x0b, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
436            (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
437            (byte) 0x04, (byte) 0x03, (byte) 0x05, (byte) 0x00,
438            (byte) 0x03, (byte) 0x2f, (byte) 0x00, (byte) 0x30,
439            (byte) 0x2c, (byte) 0x02, (byte) 0x14, (byte) 0x0e,
440            (byte) 0xbb, (byte) 0x4c, (byte) 0x61, (byte) 0x80,
441            (byte) 0xbf, (byte) 0x48, (byte) 0x48, (byte) 0x0e,
442            (byte) 0x62, (byte) 0xf4, (byte) 0x0a, (byte) 0xdf,
443            (byte) 0x17, (byte) 0xe3, (byte) 0x24, (byte) 0x86,
444            (byte) 0x5d, (byte) 0x0d, (byte) 0x09, (byte) 0x02,
445            (byte) 0x14, (byte) 0x54, (byte) 0x2f, (byte) 0xf7,
446            (byte) 0xcb, (byte) 0x7f, (byte) 0x53, (byte) 0x00,
447            (byte) 0x54, (byte) 0x47, (byte) 0x38, (byte) 0x28,
448            (byte) 0x27, (byte) 0x98, (byte) 0xcd, (byte) 0xfb,
449            (byte) 0x5d, (byte) 0x2e, (byte) 0xcc, (byte) 0xee,
450            (byte) 0x3f    
451        };
452    
453        /** 
454         * Perform self-integrity checking. Call this method in all 
455         * the constructors of your SPI implementation classes.
456         * NOTE: The following implementation assumes that all
457         * your provider implementation is packaged inside ONE jar. 
458         */
459        static final synchronized boolean selfIntegrityChecking() {
460            if (verifiedSelfIntegrity) {
461                return true;
462            }
463    
464            URL providerURL =
465                (URL) AccessController.doPrivileged(new PrivilegedAction() {
466                public Object run() {
467                    CodeSource cs =
468                        JHBCI.class.getProtectionDomain().getCodeSource();
469                    return cs.getLocation();
470                }
471            });
472    
473            if (providerURL == null) {
474                return false;
475            }
476    
477            // Open a connnection to the provider JAR file
478            JarVerifier jv = new JarVerifier(providerURL);
479    
480            // Make sure that the provider JAR file is signed with 
481            // provider's own signing certificate.
482            try {
483                if (providerCert == null) {
484                    providerCert = setupProviderCert();
485                }
486                jv.verify(providerCert);
487            } catch (Exception e) {
488                return false;
489            }
490    
491            verifiedSelfIntegrity = true;
492            
493            return verifiedSelfIntegrity;
494        }
495    
496        /*
497         * Set up 'providerCert' with the certificate bytes.
498         */
499        private static X509Certificate setupProviderCert()
500            throws IOException, CertificateException {
501            CertificateFactory cf = CertificateFactory.getInstance("X.509");
502            ByteArrayInputStream inStream =
503                new ByteArrayInputStream(bytesOfProviderCert);
504            X509Certificate cert =
505                (X509Certificate) cf.generateCertificate(inStream);
506            inStream.close();
507            return cert;
508        }
509    
510        public static class JarVerifier {
511    
512            private URL jarURL = null;
513            private JarFile jarFile = null;
514    
515            JarVerifier(URL jarURL) {
516                this.jarURL = jarURL;
517            }
518    
519            /**
520             * Retrive the jar file from the specified url.
521             */
522            private JarFile retrieveJarFileFromURL(URL url)
523                throws PrivilegedActionException, MalformedURLException {
524                JarFile jf = null;
525    
526                // Prep the url with the appropriate protocol.
527                jarURL =
528                    url.getProtocol().equalsIgnoreCase("jar")
529                        ? url
530                        : new URL("jar:" + url.toString() + "!/");
531                // Retrieve the jar file using JarURLConnection
532                jf =
533                    (
534                        JarFile) AccessController
535                            .doPrivileged(new PrivilegedExceptionAction() {
536                    public Object run() throws Exception {
537                        JarURLConnection conn =
538                            (JarURLConnection) jarURL.openConnection();
539                        // Always get a fresh copy, so we don't have to
540                        // worry about the stale file handle when the
541                        // cached jar is closed by some other application.
542                        conn.setUseCaches(false);
543                        return conn.getJarFile();
544                    }
545                });
546                return jf;
547            }
548    
549            /**
550             * First, retrieve the jar file from the URL passed in constructor.
551             * Then, compare it to the expected X509Certificate.
552             * If everything went well and the certificates are the same, no 
553             * exception is thrown.
554             */
555            public void verify(X509Certificate targetCert) throws IOException {
556                // Sanity checking
557                if (targetCert == null) {
558                    throw new SecurityException("Provider certificate is invalid");
559                }
560    
561                try {
562                    if (jarFile == null) {
563                        jarFile = retrieveJarFileFromURL(jarURL);
564                    }
565                } catch (Exception ex) {
566                    SecurityException se = new SecurityException();
567                    se.initCause(ex);
568                    throw se;
569                }
570    
571                Vector entriesVec = new Vector();
572    
573                // Ensure the jar file is signed.
574                Manifest man = jarFile.getManifest();
575                if (man == null) {
576                    throw new SecurityException("The provider is not signed");
577                }
578    
579                // Ensure all the entries' signatures verify correctly
580                byte[] buffer = new byte[8192];
581                Enumeration entries = jarFile.entries();
582    
583                while (entries.hasMoreElements()) {
584                    JarEntry je = (JarEntry) entries.nextElement();
585    
586                    // Skip directories.
587                    if (je.isDirectory())
588                        continue;
589                    entriesVec.addElement(je);
590                    InputStream is = jarFile.getInputStream(je);
591    
592                    // Read in each jar entry. A security exception will
593                    // be thrown if a signature/digest check fails.
594                    int n;
595                    while ((n = is.read(buffer, 0, buffer.length)) != -1) {
596                        // Don't care
597                    }
598                    is.close();
599                }
600    
601                // Get the list of signer certificates 
602                Enumeration e = entriesVec.elements();
603    
604                while (e.hasMoreElements()) {
605                    JarEntry je = (JarEntry) e.nextElement();
606    
607                    // Every file must be signed except files in META-INF.
608                    Certificate[] certs = je.getCertificates();
609                    if ((certs == null) || (certs.length == 0)) {
610                        if (!je.getName().startsWith("META-INF"))
611                            throw new SecurityException(
612                                "The provider " + "has unsigned " + "class files.");
613                    } else {
614                        // Check whether the file is signed by the expected
615                        // signer. The jar may be signed by multiple signers.
616                        // See if one of the signers is 'targetCert'.
617                        int startIndex = 0;
618                        X509Certificate[] certChain;
619                        boolean signedAsExpected = false;
620    
621                        while ((certChain = getAChain(certs, startIndex))
622                            != null) {
623                            if (certChain[0].equals(targetCert)) {
624                                // Stop since one trusted signer is found.
625                                signedAsExpected = true;
626                                break;
627                            }
628                            // Proceed to the next chain.
629                            startIndex += certChain.length;
630                        }
631    
632                        if (!signedAsExpected) {
633                            throw new SecurityException(
634                                "The provider "
635                                    + "is not signed by a "
636                                    + "trusted signer");
637                        }
638                    }
639                }
640            }
641    
642            /**
643             * Extracts ONE certificate chain from the specified certificate array
644             * which may contain multiple certificate chains, starting from index
645             * 'startIndex'.
646             */
647            private static X509Certificate[] getAChain(
648                Certificate[] certs,
649                int startIndex) {
650                if (startIndex > certs.length - 1)
651                    return null;
652    
653                int i;
654                // Keep going until the next certificate is not the 
655                // issuer of this certificate.
656                for (i = startIndex; i < certs.length - 1; i++) {
657                    if (!((X509Certificate) certs[i + 1])
658                        .getSubjectDN()
659                        .equals(((X509Certificate) certs[i]).getIssuerDN())) {
660                        break;
661                    }
662                }
663                // Construct and return the found certificate chain.
664                int certChainSize = (i - startIndex) + 1;
665                X509Certificate[] ret = new X509Certificate[certChainSize];
666                for (int j = 0; j < certChainSize; j++) {
667                    ret[j] = (X509Certificate) certs[startIndex + j];
668                }
669                return ret;
670            }
671    
672            // Close the jar file once this object is no longer needed.
673            protected void finalize() throws Throwable {
674                jarFile.close();
675            }
676        }
677    }